package com.ym.medical.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ym.common.utils.CalcUtil;
import com.ym.common.utils.MapUtils;
import com.ym.core.exception.BusinessException;
import com.ym.core.utils.tkmybatis.TK;
import com.ym.medical.dao.AddressGroupDao;
import com.ym.medical.dao.BankcardDao;
import com.ym.medical.dao.CertificateImageDao;
import com.ym.medical.dao.LabelsDao;
import com.ym.medical.dao.PhoneRuleDao;
import com.ym.medical.dao.ResultDoctorDao;
import com.ym.medical.dao.TextRuleDao;
import com.ym.medical.dao.YunxinUserDao;
import com.ym.medical.domain.entity.*;
import com.ym.medical.domain.param.DoctorDetailsParam;
import com.ym.medical.domain.param.ExamDoctorParam;
import com.ym.medical.domain.param.PhoneRuleModel;
import com.ym.medical.domain.vo.*;
import com.ym.medical.enums.PriceIntervalEnum;
import com.ym.medical.enums.RelevantCertRecordAuditStatus;
import com.ym.medical.enums.UserCertStateEnum;
import com.ym.medical.service.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class ResultDoctorSVImpl implements IResultDoctorSV {
	private static final Logger LOGGER = LoggerFactory.getLogger(ResultDoctorSVImpl.class);
	private static final int PARSE_OK = 1;

	@Resource
	private ResultDoctorDao resultDoctorDao;

	@Autowired
	private LabelsDao labelsDao;
	@Autowired
	private CertificateImageDao certificateImageDao;
	@Autowired
	private TextRuleDao textRuleDao;
	@Autowired
	private PhoneRuleDao phoneRuleDao;
	@Autowired
	private ISysDictSV sysDictDao;
	@Autowired
	private BankcardDao bankcardDao;
	@Autowired
	private AddressGroupDao addressGroupDao;
	@Autowired
	private IDoctorDetailsSV doctorDetailsSV;
	@Autowired
	private YunxinUserDao yunxinUserDao;

	@Autowired
	private IStudioPersonnelSV studioPersonnelSV;

	@Autowired
	private IUserTaglibrarySV userTaglibrarySV;

	@Autowired
	private IStandarTaglibrarySV standarTaglibrarySV;

	@Autowired
	private ICustomTaglibrarySV customTaglibrarySV;

	@Autowired
	private IUserSV userSV;

	@Autowired
	private IRelevantCertRecordSV relevantCertRecordSV;

	@Autowired
	private IDsAdviseRecordSV dsAdviseRecordSV;

	@Autowired
	private IInquiryOrderSV inquiryOrderSV;

	/**
	 * 根据医生id获取云信账号
	 *
	 * @param doctorId
	 * @return
	 */
	private String getYxAccByUserId(Long doctorId) {
		List<YunxinUserEntity> yunxinUsers = yunxinUserDao.select(YunxinUserEntity.builder().userId(doctorId).build());
		return (yunxinUsers.size() > 0) ? yunxinUsers.get(0).getAccid() : null;
	}

	/**
	 * 查询银行卡列表
	 *
	 * @param currentId
	 * @return
	 */
	@Override
	public List<BankcardEntity> listBankCard(Long currentId) {
		return bankcardDao.select(BankcardEntity.builder().userId(currentId).build());
	}

	@Override
	public List<ResultDoctor> selectByExamDoctor(ExamDoctorParam examDoctor) {
		// 推荐记录ID设置
		if (examDoctor.getAdviseId() != null && examDoctor.getAdviseId().length > 0) {
			List<DsAdviseRecordEntity> dsAdviseRecords = dsAdviseRecordSV.selectList(
					TK.select(DsAdviseRecordEntity.class).where()
							.andIn(DsAdviseRecordEntity::getId, examDoctor.getAdviseId())
							.end()
			);
			Long[] longs = dsAdviseRecords.stream().map(DsAdviseRecordEntity::getBeadvisedDoctorId).toArray(Long[]::new);
			examDoctor.setAdviseId(longs);
		} else {
			examDoctor.setAdviseId(null);
		}
		//2. 构建价格条件
		String prices = examDoctor.getPrice();
		if (!StringUtils.isBlank(prices)) {
			String priceSql = "(";
			String textpriceSql = "";
			String phonePriceSql = "";
			if (!prices.contains(",")) {
				String priceInterval = sysDictDao.getDictValue(PriceIntervalEnum.class, prices);
				String[] split = priceInterval.split("-");
				if (!PriceIntervalEnum.FOURTHPRICE.getKey().equals(prices)) {
					textpriceSql += "(a.text_min_price BETWEEN " + split[0] + " AND " + split[1] + ")";
					phonePriceSql += "(b.phone_min_price BETWEEN " + split[0] + " AND " + split[1] + ")";
				} else {
					textpriceSql += "(a.text_min_price <![CDATA[ >= ]]> " + split[0] + ")";
					phonePriceSql += "(b.phone_min_price <![CDATA[ >= ]]> " + split[0] + ")";
				}
			} else {
				String[] priceArr = prices.split(",");
				textpriceSql += "(";
				phonePriceSql += "(";
				for (String price : priceArr) {
					String priceInterval = sysDictDao.getDictValue("PriceIntervalEnum", price);
					String[] split = priceInterval.split("-");
					if (!PriceIntervalEnum.FOURTHPRICE.getKey().equals(price)) {
						textpriceSql += "(a.text_min_price BETWEEN " + split[0] + " AND " + split[1] + ") OR ";
						phonePriceSql += "(b.phone_min_price BETWEEN " + split[0] + " AND " + split[1] + ") OR ";
					} else {
						textpriceSql += "(a.text_min_price <![CDATA[ >= ]]> " + split[0] + ") OR ";
						phonePriceSql += "(b.phone_min_price <![CDATA[ >= ]]> " + split[0] + ") OR ";
					}
				}
				textpriceSql = textpriceSql.substring(0, textpriceSql.length() - 3) + ")";
				phonePriceSql = phonePriceSql.substring(0, phonePriceSql.length() - 3) + ")";
			}

			priceSql = priceSql + textpriceSql + " OR " + phonePriceSql + ")";
			examDoctor.setPrice(priceSql);
		}
		List<ResultDoctor> doctorDetails = resultDoctorDao.selectByExamDoctor(examDoctor);
		for (ResultDoctor doctorDetail : doctorDetails) {
			//4. 根据患者医院的经纬度 计算距离  //获取医院的经度纬度
			Double userLongitude = examDoctor.getUserLongitude();
			Double userLatitude = examDoctor.getUserLatitude();
			Double hosLongitude = doctorDetail.getHosLongitude();
			Double hosLatitude = doctorDetail.getHosLatitude();
			if (userLongitude != null && userLatitude != null && hosLongitude != null && hosLatitude != null) {
				Double distance = MapUtils.getDistance(userLongitude, userLatitude, hosLongitude, hosLatitude);
				doctorDetail.setDistance(new BigDecimal(distance).divide(new BigDecimal(1000), 1, BigDecimal.ROUND_HALF_UP).toString());
			}

			//5. 计算义诊折扣
			BigDecimal textMinPrice = doctorDetail.getTextMinPrice();
			BigDecimal textClinicPrice = doctorDetail.getTextClinicPrice();
			if (textMinPrice != null && textClinicPrice != null) {
				if ((textClinicPrice.compareTo(BigDecimal.ZERO) == 1) && (textMinPrice.compareTo(BigDecimal.ZERO) == 1)) {
					doctorDetail.setTextClinicRebate(CalcUtil.div(textClinicPrice, textMinPrice).decimalValue(2));
				}
			}
		}
		//按照距离排序
		Collections.sort(doctorDetails, new Comparator<ResultDoctor>() {
			@Override
			public int compare(ResultDoctor o1, ResultDoctor o2) {
				if (o1.getDistance() != null && o2.getDistance() != null) {
					return o1.getDistance().compareTo(o2.getDistance());
				}
				return 0;
			}
		});
		return doctorDetails;
	}

	@Override
	public void authentication(List<RelevantCertRecordEntity> relevantCertRecords, UserEntity user) {
		//查询当前用户的信息
		Long currentUserId = user.getId();
		DoctorDetailsEntity doctorDetails = doctorDetailsSV.selectById(currentUserId);
		if (UserCertStateEnum.AUTHORIZEDING.getKey().equals(doctorDetails.getQualificationStatus())) {
			throw new BusinessException("你的资质正在认证中");
		}
		String realName = user.getRealName();
		String sex = user.getSex();
		String contactAddr = user.getContactAddr();
		String cardNo = user.getCardNo();
		for (RelevantCertRecordEntity relevantCertRecord : relevantCertRecords) {
			relevantCertRecord.setUserId(currentUserId);
			relevantCertRecord.setUserName(realName);
			relevantCertRecord.setUserSex(sex);
			relevantCertRecord.setTheAddress(contactAddr);
			relevantCertRecord.setCertNo(cardNo);
			relevantCertRecord.setCreatePerson(currentUserId);
			relevantCertRecord.setAuditPerson(currentUserId);
			relevantCertRecord.setAuditStatus(RelevantCertRecordAuditStatus.TO_AUDIT.getKey());
			relevantCertRecordSV.insert(relevantCertRecord);
			//修改医生的资质认证状态
			doctorDetails.setQualificationStatus(UserCertStateEnum.AUTHORIZEDING.getKey());
			doctorDetailsSV.updateById(doctorDetails);

		}
	}

	@Override
	public ClinicDoctorVO listFreeClinicDoctor(int pageNum, int pageSize, ExamDoctorParam examDoctor) {
		ClinicDoctorVO clinicDoctorVO = new ClinicDoctorVO();
		//判断该患者的义诊次数
		List<Long> doctors = inquiryOrderSV.queryClinicTime(examDoctor.getCurrentId());
		if (doctors != null && doctors.size() >= 3) {
			LOGGER.info("一个患者一周内只能义诊三次");
			clinicDoctorVO.setIsClinic(false);
		} else {
			clinicDoctorVO.setIsClinic(true);
		}
		clinicDoctorVO.setResultDoctor(listPage(pageNum, pageSize, examDoctor));
		return clinicDoctorVO;
	}

	@Override
	public PageInfo<ResultDoctor> listPage(int pageNum, int pageSize, ExamDoctorParam examDoctor) {
		PageHelper.startPage(pageNum, pageSize);
		List<ResultDoctor> doctorDetails = selectByExamDoctor(examDoctor);
		return new PageInfo<>(doctorDetails);
	}

	/**
	 * @param examDoctor 医生构造条件
	 * @return
	 */
	@Override
	public ResultDocDetailVo selectByDoctorId(ExamDoctorParam examDoctor) {
		Long userId = examDoctor.getUserId();
		ResultDocDetailVo resultDocDetail = resultDoctorDao.selectByUid(examDoctor);
		/*查询医生的,资质认证*/
		List<CertificateImageEntity> certificateImages = certificateImageDao.select(CertificateImageEntity.builder().doctId(userId).build());
		if (certificateImages.size() > 0) {
			resultDocDetail.setCertificateImages(certificateImages);
		}

		//根据患者医院的经纬度 计算距离
		Double userLongitude = examDoctor.getUserLongitude();
		Double userLatitude = examDoctor.getUserLatitude();
		//获取医院的经度纬度
		Double hosLongitude = resultDocDetail.getHosLongitude();
		Double hosLatitude = resultDocDetail.getHosLatitude();
		//计算两个经纬度之间的距离
		if (userLongitude != null && userLatitude != null && hosLongitude != null && hosLatitude != null) {
			Double distance = MapUtils.getDistance(userLongitude, userLatitude, hosLongitude, hosLatitude);
			resultDocDetail.setDistance(new BigDecimal(distance).divide(new BigDecimal(1000), 1, BigDecimal.ROUND_HALF_UP).toString());
		}

		/*查詢医生的银行卡*/
		List<BankcardEntity> bankcards = bankcardDao.select(BankcardEntity.builder().userId(userId).build());
		if (bankcards.size() > 0) {
			resultDocDetail.setBankcards(bankcards);
		}
		return resultDocDetail;
	}

	@Override
	public IndexDoctorsVO searchDoctor(ExamDoctorParam examDoctor, int pageSize, int pageNum) {
		//todo 待实现
		return null;
	}


	@Override
	public PageInfo<LabelsEntity> selectDoctorGood(Long doctorId, int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize);
		List<LabelsEntity> labels = labelsDao.selectGoodLabelDoctorId(doctorId);
		return new PageInfo<LabelsEntity>(labels);
	}

	@Override
	public boolean editDoctorGood(List<LabelsEntity> labels, Long doctorId) {
		for (LabelsEntity label : labels) {
			int flag = labelsDao.insertSelective(label);
			if (flag != PARSE_OK) {
				return false;
			}
			/*关联医生标签表*/
			flag = labelsDao.insertDoctorLabel(label.getId(), doctorId);
			if (flag != PARSE_OK) {
				return false;
			}
		}
		return true;
	}

	@Override
	public boolean delDoctorGood(Long labId, Long doctId) {
		/*取消医生表的关联*/
		int flag = labelsDao.delectDoctorLabel(labId, doctId);

		return true;

	}

	@Override
	public PageInfo<ResultDoctor> collectDoctorList(int pageNum, int pageSize, Long userId) {
		PageHelper.startPage(pageNum, pageSize);
		ExamDoctorParam examDoctor = new ExamDoctorParam();
		examDoctor.setUserId(userId);
		List<ResultDoctor> resultDoctors = resultDoctorDao.selectByExamDoctor(examDoctor);
		return new PageInfo<ResultDoctor>(resultDoctors);
	}

	@Override
	public ResultDocDetailVo selectPriceRule(Long userId) {
		Map<String, Object> map = new HashMap<>();
		//查询医生个人信息
		ExamDoctorParam examDoctor = new ExamDoctorParam();
		examDoctor.setUserId(userId);
		ResultDocDetailVo resultDocDetail = selectByDoctorId(examDoctor);
		//查询医生图文定价规则
		List<TextRuleVo> textRuleModel = textRuleDao.selectTextItem(userId);
		resultDocDetail.setTextRuleModels(textRuleModel);
		return resultDocDetail;
	}

	/**
	 * 查询医生服务项
	 *
	 * @param userId
	 * @return
	 */
	@Override
	public DoctorServiceItemsVo selectserviceItem(Long userId) {
		DoctorServiceItemsVo doctorServiceItemsVo = new DoctorServiceItemsVo();
		//查询医生图文服务项
		List<TextRuleVo> textRuleModel = textRuleDao.selectTextItem(userId);
		if (textRuleModel.size() > 0) {
			doctorServiceItemsVo.setTextRuleModel(textRuleModel);
		}
		//查询医生电话服务项
		List<PhoneRuleModel> phoneRuleModel = phoneRuleDao.selectPhoneItem(userId);
		if (phoneRuleModel.size() > 0) {
			doctorServiceItemsVo.setPhoneRuleModel(phoneRuleModel.get(0));
		}
		//查询医生私人服务项
		// todo 待实现
		return doctorServiceItemsVo;
	}

	@Override
	public DoctorDetailAllInfoVo selectDoctorDetail(Long userId) {
		DoctorDetailsParam doctorDetailsModel = new DoctorDetailsParam();
		doctorDetailsModel.setId(userId);
		List<DoctorDetailAllInfoVo> doctorDetailAllInfoVo = doctorDetailsSV.listDoctorAllInfo(doctorDetailsModel);
		if (doctorDetailAllInfoVo.isEmpty()) {
			return null;
		}
		DoctorDetailAllInfoVo result = doctorDetailAllInfoVo.get(0);
		// 设置银行卡列表
		List<BankcardEntity> bankcards = listBankCard(userId);
		if (!bankcards.isEmpty()) {
			result.setBankcards(bankcards);
		}
		return result;
	}

	/**
	 * 查询医生个人信息
	 *
	 * @param userId
	 * @return
	 */
	@Override
	public ResultDocDetailVo findDoctorById(ExamDoctorParam examDoctor, Long userId) {
		//设置医生id
		Long doctorId = examDoctor.getUserId();
		examDoctor.setCurrentId(userId);
		ResultDocDetailVo resultDocDetail = resultDoctorDao.selectByUid(examDoctor);

		List<String> list = new ArrayList<>();
		//获取医生工作室id
		Long dsId = resultDocDetail.getDsId();
		if (dsId == null) {
			//查询医生云信账户
			list.add(getYxAccByUserId(doctorId));
			resultDocDetail.setYxAccId(list);
		} else {
			//查询医生工作室下的所有成员
			List<StudioPersonnelEntity> studioPersonnels = studioPersonnelSV.selectList(StudioPersonnelEntity.builder().build().builder().dsId(dsId).build());
			for (StudioPersonnelEntity studioPersonnel : studioPersonnels) {
				Long doctId = studioPersonnel.getDoctId();
				//查询医生云信账户
				list.add(getYxAccByUserId(doctId));
			}
			resultDocDetail.setYxAccId(list);
		}
		//查询医生服务项
		resultDocDetail.setDoctorServiceItemsVo(selectserviceItem(doctorId));

		//如果是小程序端 患者id与医生id不同
		if (userId != null && (!userId.equals(doctorId))) {
			//查看该医生是否已被关注
			AddressGroupVo attentionPatient = addressGroupDao.getAttention(doctorId, userId);
			if (attentionPatient != null) {
				resultDocDetail.setAttention(true);
				resultDocDetail.setAttentionId(attentionPatient.getAlId());
			} else {
				resultDocDetail.setAttention(false);
			}
			//根据患者医院的经纬度 计算距离
			Double userLongitude = examDoctor.getUserLongitude();
			Double userLatitude = examDoctor.getUserLatitude();
			//获取医院的经度纬度
			Double hosLongitude = resultDocDetail.getHosLongitude();
			Double hosLatitude = resultDocDetail.getHosLatitude();
			//计算两个经纬度之间的距离
			if (userLongitude != null && userLatitude != null && hosLongitude != null && hosLatitude != null) {
				Double distance = MapUtils.getDistance(userLongitude, userLatitude, hosLongitude, hosLatitude);
				resultDocDetail.setDistance(new BigDecimal(distance).divide(new BigDecimal(1000), 1, BigDecimal.ROUND_HALF_UP).toString());
			}
		}
		return resultDocDetail;
	}


	/**
	 * 热度咨询
	 *
	 * @param userId
	 * @param doctorId
	 * @param possDisease
	 * @return
	 */
	@Override
	public HotConsultationVo hotConsultation(Long userId, Long doctorId, String possDisease, int pageNum, int pageSize) {
		HotConsultationVo hotConsultation = new HotConsultationVo();
		List<PatientInfoVo> patientInfos = resultDoctorDao.selectPatient(userId, doctorId, possDisease);
		hotConsultation.setPatientInfo(patientInfos);
//		for (PatientInfo patientInfo : patientInfos) {
//			//查询该订单的评价标签
//			List<UserTaglibraryModel> list = new ArrayList<>();
//			List<UserTaglibrary> userTaglibraries = userTaglibrarySV.selectByOrderId(patientInfo.getIoId(), doctorId, patientInfo.getUserId());
//			for (UserTaglibrary userTaglibrary : userTaglibraries) {
//				UserTaglibraryModel model = new UserTaglibraryModel();
//				BeanUtils.copyProperties(userTaglibrary, model);
//				//判断该标签的类型
//				String tagType = userTaglibrary.getTagType();
//				if (UserTaglibraryTagTypeEnum.STANDARD_TAG.getKey().equals(tagType)) {
//					//标准标签
//					StandarTaglibrary standarTaglibrary = standarTaglibrarySV.selectById(userTaglibrary.getTagId());
//					model.setTglbName(standarTaglibrary.getTglbName());
//				} else if (UserTaglibraryTagTypeEnum.CUSTOMER_TAG.getKey().equals(tagType)) {
//					//自定义标签
//					CustomTaglibrary customTaglibrary = customTaglibrarySV.selectById(userTaglibrary.getTagId());
//					model.setTglbName(customTaglibrary.getTglbName());
//				}
//				list.add(model);
//			}
//		}
		return hotConsultation;
	}

	/**
	 * 咨询总结标签
	 *
	 * @param doctorId
	 * @return
	 */
	@Override
	public HotConsultationVo conclusionLabel(Long doctorId, int pageNum, int pageSize) {
		HotConsultationVo hotConsultation = new HotConsultationVo();
		//查询医生的咨询总结
		List<ConsultSummaryEntity> consultSummary = resultDoctorDao.selectConsultSummary(doctorId);
		if (!consultSummary.isEmpty()) {
			hotConsultation.setConsultSummary(consultSummary);
			hotConsultation.setConsultSummaryNum(consultSummary.size());
		}
		List<PatientInfoVo> patientInfos = resultDoctorDao.selectPatient(null, doctorId, null);
		hotConsultation.setCountSummaryNum(patientInfos.size());
		return hotConsultation;
	}
}
